package cn.livingCloud.security;

import cn.livingCloud.service.UserAccountService;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.cas.CasToken;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.util.StringUtils;


public class UserAuthorizingRealm extends AuthorizingRealm {

    private UserAccountService userAccountService;

    public UserAuthorizingRealm() {
        super();
    }

    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof CasToken || super.supports(token);
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        return userAccountService.doGetAuthorizationInfo(principals, new SimpleAuthorizationInfo());
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
        if (authcToken instanceof CasToken) {
            CasToken token = (CasToken) authcToken;
            String memberCode = (String) token.getCredentials();
            return userAccountService.loginMember(memberCode);
        }

        if (authcToken instanceof UsernamePasswordToken) {
            UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
            String username = token.getUsername();
            String password = String.valueOf(token.getPassword());
            if (!StringUtils.isEmpty(username)) {
                return userAccountService.login(username, password);
            }
        }
        return null;
    }

    public UserAuthorizingRealm setUserAccountService(UserAccountService userAccountService) {
        this.userAccountService = userAccountService;
        return this;
    }
}
